
lua_extension = lua_extension or {};

local Socket = commonlib.inherit(nil);

local function IsEmscriptenPlatform()
    return commonlib.GetPlatform() == commonlib.IPlatform_EMSCRIPTEN;
end

function Socket:Init(socket_type)
    self.m_socket = commonlib.LuaSocket(socket_type);
    self.m_connected = false;
    self.m_socket:OnConnect(function()
        self:OnConnectCallBack();
    end);

    self.m_socket:OnReceive(function(data)
        self:OnReceiveCallBack(data);
    end);

    self.m_socket:OnClose(function()
        self:OnCloseCallBack();
    end);
    return self;
end

function Socket:SetTimeout(ms)
    self.m_socket:SetTimeout(ms);
end

function Socket:OnConnect(callback)
    self.m_on_connect_callback = callback;
end

function Socket:OnReceive(callback)
    self.m_on_receive_callback = callback;
end

function Socket:OnClose(callback)
    self.m_on_close_callback = callback;
end

function Socket:Connect(ip, port, callback)
    self.m_on_connect_callback = callback or self.m_on_connect_callback;
    return self.m_socket:Connect(ip, port, type(self.m_on_connect_callback) ~= "function");
end

function Socket:Send(data)
    if (not self.m_connected) then return false, "closed" end
    return self.m_socket:Send(data);
end

function Socket:Receive()
    if (not self.m_connected) then return false, "closed" end
    return self.m_socket:Receive();
end

function Socket:Close()
    -- print("Close Socket");
    self.m_socket:Close();
end

function Socket:OnConnectCallBack()
    self.m_connected = true;
    -- print("===========OnConnectCallBack=============")
    if (type(self.m_on_connect_callback) == "function") then self.m_on_connect_callback() end
end

function Socket:OnReceiveCallBack(data)
    -- print("===========OnReceiveCallBack=============", data)
    if (type(self.m_on_receive_callback) == "function") then self.m_on_receive_callback(data) end
end

function Socket:OnCloseCallBack()
    -- print("===========OnCloseCallBack=============")
    self.m_connected = false;
    if (type(self.m_on_close_callback) == "function") then self.m_on_close_callback() end
end

function commonlib.NewTcpSocket()
    return Socket:new():Init("tcp");
end

local luasocket = {};
function luasocket.tcp()
    local tcp = {m_socket = Socket:new():Init("tcp")};
    function tcp:close()
        return self.m_socket:Close();
    end
    function tcp:connect(ip, port)
        return self.m_socket:Connect(ip, port)
    end
    function tcp:send(data)
        return self.m_socket:Send(data);
    end
    function tcp:receive()
        local data = self.m_socket:Receive();
        if (data == "") then return nil end
        return data;
    end
    function tcp:close()
        return self.m_socket:Close();
    end
    function tcp:settimeout(s)
        return self.m_socket:SetTimeout(s * 1000);
    end
    return tcp;
end

if (IsEmscriptenPlatform()) then
    lua_extension.luasocket = function ()
        return luasocket;
    end;
end
